﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.ExtentionMethods;
using Happy.Query.Filters.Internal;
using Happy.Query.Filters.Configuration;
using Happy.Query.Filters.Configuration.Internal;

namespace Happy.Query.Filters
{
    /// <summary>
    /// 筛选器定义。
    /// </summary>
    public sealed class FilterDefinition
    {
        private readonly Dictionary<string, Parameter> _parameters = new Dictionary<string, Parameter>();

        private FilterDefinition()
        {
        }

        /// <summary>
        /// 构造方法。
        /// </summary>
        public FilterDefinition(IFilter filter)
        {
            this.Filter = filter;
        }

        /// <summary>
        /// 定义筛选器定义。
        /// </summary>
        public static FilterDefinition Define(
            Action<FilterDefinition> action,
            Func<IConfig, IFilter> factory)
        {
            var definition = new FilterDefinition();

            action(definition);
            definition.Filter = factory(new Config());

            return definition;
        }

        /// <summary>
        /// 筛选器。
        /// </summary>
        public IFilter Filter { get; private set; }

        /// <summary>
        /// 参数列表。
        /// </summary>
        public Dictionary<string, Parameter> Parameters
        {
            get { return _parameters; }
        }

        /// <summary>
        /// 定义参数。 
        /// </summary>
        public FilterDefinition DefineParameter(Parameter parameter)
        {
            parameter.MustNotNull("parameter");

            _parameters.Add(parameter.Name, parameter);

            return this;
        }

        /// <summary>
        /// 定义参数。 
        /// </summary>
        public FilterDefinition DefineParameter(string name, Boolean required = false)
        {
            return this.DefineParameter(new Parameter(name, required));
        }

        /// <summary>
        /// 构造 Where 字句。
        /// </summary>
        public WhereClause BuildWhereClause()
        {
            return this.BuildWhereClause(new Dictionary<string, object>());
        }

        /// <summary>
        /// 构造 Where 字句。
        /// </summary>
        public WhereClause BuildWhereClause(IDictionary<string, object> arguments)
        {
            var validFilterBuilder = new ValidFilterBuilder(this.Parameters, arguments);
            this.Filter.Accept(validFilterBuilder);
            var validFilter = validFilterBuilder.GetFilter();

            var whereClauseBuilder = new WhereClauseBuilder(arguments);
            validFilter.Accept(whereClauseBuilder);
            return whereClauseBuilder.GetWhereClause();
        }
    }
}
